#include "PbMessageConverter.h"
#include <activemq/commands/ActiveMQBytesMessage.h>
#include <string>

#include "badpbmessageexception.h"
#include "unsupportedcmsmessageexception.h"
#include "entity/marketprice.pb.h"
#include <google/protobuf/descriptor.h>

PbMessageConverter::PbMessageConverter(void)
{
}

PbMessageConverter::~PbMessageConverter(void)
{
}

cms::Message* PbMessageConverter::toCmsMessage(void *object)
{
	google::protobuf::Message* pbMsg = static_cast<google::protobuf::Message*>(object);
	return toCmsMessage(pbMsg);
}

void* PbMessageConverter::toObject(const cms::Message* cmsMessage)
{
	return toPbMessage(cmsMessage);
}

cms::Message* PbMessageConverter::toCmsMessage(const google::protobuf::Message* pbMsg)
{
	activemq::commands::ActiveMQBytesMessage* cmsMsg = new activemq::commands::ActiveMQBytesMessage();
	std::string output;
	cmsMsg->setStringProperty("dtotype", pbMsg->GetTypeName());
	if(pbMsg->SerializeToString(&output))
	{
		cmsMsg->setBodyBytes(reinterpret_cast<const unsigned char*>( output.c_str()), output.size());
		return cmsMsg;
	}
	else
	{
		throw BadPbMessageException();
	}

}
google::protobuf::Message* PbMessageConverter::toPbMessage(const cms::Message* cmsMessage)
{
	const activemq::commands::ActiveMQBytesMessage* cmsMsg = dynamic_cast<const activemq::commands::ActiveMQBytesMessage*>(cmsMessage);
	if(cmsMsg == NULL)
	{
		throw UnsupportedCmsMessageException();
	}

	std::string dtotype = cmsMessage->getStringProperty("dtotype");
	/*if(dtotype == "poc.entity.MarketPrice")
	{
	poc::entity::MarketPrice* price = new poc::entity::MarketPrice();
	price->ParseFromArray(cmsMsg->getBodyBytes(),cmsMsg->getBodyLength());
	return price;
	}*/
	google::protobuf::Message* message = NULL;
	const google::protobuf::Descriptor* descriptor = google::protobuf::DescriptorPool::generated_pool()->FindMessageTypeByName(dtotype);
	if (descriptor)
	{
		const google::protobuf::Message* prototype =	google::protobuf::MessageFactory::generated_factory()->GetPrototype(descriptor);
		if (prototype)
		{
			message = prototype->New();
			message->ParseFromArray(cmsMsg->getBodyBytes(),cmsMsg->getBodyLength());
		}
	}
	return message;

}
